﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Collections;
using System.Data.SqlClient;
using AccesoBD;
using System.Data;
using CapaLogica.CL.Bitacora;
using CapaLogica.CL.UtilidadesGenerales;

namespace CapaLogica.CL.Carrera
{
    public class CarreraPersistente
    {
        
        AcessoBD _acceso = new AcessoBD();

        /// <summary>
        /// Método de la clase encargada de insertar una nueva Carrera a la BD
        /// </summary>
        /// <param name="pGrupo">Objeto carrera, tipo Carrera</param>
        /// <param name="pUsuario">Usuario que realiza la accion, tipo int</param>
        /// <remarks></remarks>
        internal void registrarCarrera(Cl_Carrera pcarrera, int pIdUsuario)//parametros del grupo
        {
            Parametros[] parametros = new Parametros[3];
            String sql = @"insert into dbo.T_Carrera(codigo_carrera, nombre, descripcion)
                                values(param1, param2, param3) ";

            parametros[0] = new Parametros(pcarrera.Codigo, "param1");
            parametros[1] = new Parametros(pcarrera.Nombre, "param2");
            parametros[2] = new Parametros(pcarrera.Descripcion, "param3");

            try
            {
                pcarrera.Id = _acceso.executeSQLInsert(sql, parametros);

                if (pcarrera.Id != -1)
                {
                    //BITACORA
                    Modulo.insertarBitacora(pIdUsuario, "Creación de un nueva Carrera", pcarrera.Id, 3, 1);
                    //---------------
                }
            }
            catch (Exception ex)
            {
                SqlException exsql = ex as SqlException;
                SqlError er = exsql.Errors[0];

                if (er.Number == 2601)
                {
                    throw new Exception("Ya hay una carrera con el mismo código.");
                }
                else
                {
                    throw new Exception("Ha habido un error al registrar la carrera. " + er.Number);
                }
            }
        }


        internal List<EsCarrera> buscarCarrera(String pcodigoCarrera, String pnombre)//parametros del grupo
        {
            List<EsCarrera> carreras = new List<EsCarrera>();

            EsCarrera carrera;
            string psp = @"dbo.sp_buscar_carreras_por_nombre_codigo";

            Parametros[] parametros = new Parametros[2];
            parametros[0] = new Parametros(pcodigoCarrera, "codigo_carrera");
            parametros[1] = new Parametros(pnombre, "nombre");

            try
            {
                SqlDataReader reader = _acceso.execute_SP_Consulta(psp, parametros);

                while (reader.Read())
                {
                    carrera = new EsCarrera();
                    carrera.Id = reader.GetValue(0).ToString();
                    carrera.Codigo = reader.GetValue(1).ToString();
                    carrera.Nombre = reader.GetValue(2).ToString();
                    carrera.Descripcion = reader.GetValue(3).ToString();
                    carrera.DirectorAcademico = reader.GetValue(4).ToString();
                    carrera.IdDirector = reader.GetInt32(5);
                    carreras.Add(carrera);
                }
                reader.Close();

                return carreras;

            }
            catch (Exception ex)
            {
                throw new System.Exception(ex.Message);
            }

        }


        /// <summary>
        /// Método de la clase encargada de insertar una nueva Carrera a la BD
        /// </summary>
        /// <param name="pGrupo">Objeto carrera, tipo Carrera</param>
        /// <param name="pUsuario">Usuario que realiza la accion, tipo int</param>
        /// <remarks></remarks>
        internal void eliminarCarrera(int pidCarrera, int pIdUsuario)//parametros del grupo
        {

            Parametros[] parametros = new Parametros[1];
            String sql = @"Delete dbo.T_Carrera where dbo.T_Carrera.id_carrera = param1";


            parametros[0] = new Parametros(pidCarrera, "param1");

            try
            {

                _acceso.executeSQL(sql, parametros);
                 //BITACORA
                Modulo.insertarBitacora(pIdUsuario, "Eliminacion de una Carrera", pidCarrera, 3, 2);
                    //---------------    
            }
            catch (Exception ex)
            {
                SqlException exsql = ex as SqlException;
                SqlError er = exsql.Errors[0];

                if (er.Number == 547)
                {
                    throw new Exception("Esta carrera esta asociada a otras entidades asi que no se puede borrar");
                }
                else
                {
                    throw new Exception("Ha habido un error al eliminar la carrera. " + er.Number);
                }
            }

        }




        internal void actualizarCarrera(Cl_Carrera pcarrera, List<int> pIdsAP, List<int> pIdsBD, int pidUsuario, int idDirector, int idViejo)
        {

            try
            {

                Parametros[] parametros = new Parametros[4];

                string sql = @"update dbo.T_Carrera set codigo_carrera = param1, nombre = param2, descripcion = param3 where id_carrera = param0";

                parametros[0] = new Parametros(pcarrera.Id, "param0");
                parametros[1] = new Parametros(pcarrera.Codigo, "param1");
                parametros[2] = new Parametros(pcarrera.Nombre, "param2");
                parametros[3] = new Parametros(pcarrera.Descripcion, "param3");
                

                _acceso.executeSQL(sql, parametros);

                if (idViejo == 0)
                {

                    Parametros[] parametros1 = new Parametros[2];

                    sql = @"insert into dbo.T_Director_Carrera(id_director, id_carrera) values(param0, param1)";

                    parametros1[0] = new Parametros(idDirector, "param0");
                    parametros1[1] = new Parametros(pcarrera.Id, "param1");

                    int numDirector = _acceso.executeSQLInsert(sql, parametros1);

                }
                else 
                {

                    Parametros[] parametros1 = new Parametros[2];

                    sql = @"update dbo.T_Director_Carrera set id_director = param0 where id_carrera = param1";

                    parametros1[0] = new Parametros(idDirector, "param0");
                    parametros1[1] = new Parametros(pcarrera.Id, "param1");

                    //int numDirector = _acceso.executeSQLInsert(sql, parametros1);
                    _acceso.executeSQL(sql, parametros1);

                }

                try
                {
                    string sqlUpdate = @"delete from dbo.T_Curso_Carrera 
                                    where id_carrera = param1 and
                                    id_curso = param2 and                      
                                    estado = 1";

                    string sqlInsert = @"insert into dbo.T_Curso_Carrera(id_carrera, id_curso, estado)
                                    values(param1, param2, 1)";

                    EsBitacora bitacora = new EsBitacora();
                    bitacora.IdUsuario = pidUsuario;
                    bitacora.Descripcion = "Cambio de los cursos asociados a una carrera";
                    bitacora.Tipo = "3";


                    Parametros[] paramUpdate = new Parametros[2];
                    paramUpdate[0] = new Parametros(pcarrera.Id, "param1");
                    paramUpdate[1] = new Parametros("", "param2");


                    Parametros[] paramInsert = new Parametros[2];
                    paramInsert[0] = new Parametros(pcarrera.Id, "param1");
                    paramInsert[1] = new Parametros("", "param2");

                    Modulo.comparaListas(pIdsAP, pIdsBD, sqlUpdate, sqlInsert, paramUpdate, paramInsert, bitacora, null);
                }
                catch (Exception ex)
                {
                    throw ex;
                }

            }
            catch (Exception)
            {

                throw new Exception("Hubo un error al intentar modificar la carrera. La carrera no ha sido modificada.");
            }
            

        }




        /// <summary>
        /// Método de la clase que busca los ids de las carreras de un estudiante.
        /// </summary>
        /// <param name="pIdGrupo">In del grupo, tipo int</param>
        /// <remarks></remarks>
        internal List<int> buscarIdsCarrerasDeEstudiante(int pIdEstudiante)
        {

            string psp = @"dbo.sp_buscar_ids_carreras";
            Parametros[] parametros = new Parametros[1];
            parametros[0] = new Parametros(pIdEstudiante, "idEstudiante");

            try
            {
                SqlDataReader reader = _acceso.execute_SP_Consulta(psp, parametros);
                List<int> ids = new List<int>();
                while (reader.Read())
                {
                    ids.Add(reader.GetInt32(0));
                }

                reader.Close();
                return ids;

            }
            catch (Exception ex)
            {
                throw ex;
            }

        }


        internal Cl_Carrera buscarCarreraPorId(int pIdCarrera)//parametros del grupo
        {

            string psp = @"dbo.sp_buscar_carrera_id";
            Cl_Carrera carrera = null;
            Parametros[] parametros = new Parametros[1];
            parametros[0] = new Parametros(pIdCarrera, "id_carrera");
            try
            {
                SqlDataReader reader = _acceso.execute_SP_Consulta(psp, parametros);

                if (reader.Read())
                {
                    carrera = new Cl_Carrera((String)reader["_codigo_carrera"], (String)reader["nombre"], (String)reader["descripcion"]);
                }

                reader.Close();
                return carrera;

            }
            catch (Exception ex)
            {
                throw new System.Exception(ex.Message);
            }

        }

        
        /// <summary>
        /// Método de la clase encargada de cambiar las carreras de un estudiante
        /// </summary>
        /// <param name="pIdEstudiante">pIdEstudiante, tipo int</param>
        /// <param name="pIdsAp">Ids de las  carreras seleccionadas, tipo List</int></param>
        /// <param name="pIdsBD">Ids de las carreras de la BD, tipo List</int></param>
        /// <param name="pUsuario">Usuario que realiza la accion, tipo int</param>
        /// <remarks></remarks>
        internal void cambiarCarrerasEstudiante(int pIdEstudiante, List<int> pIdsAP, List<int> pIdsBD, int pIdUsuario)
        {
            try
            {
                EsBitacora bitacora = new EsBitacora();
                bitacora.Descripcion = "Cambio de la carrera de un estudiante";
                bitacora.IdUsuario = pIdUsuario;
                bitacora.Tipo = "Carrera Estudiante";

                string sqlUpdate = @"Update dbo.T_Estudiante_Carrera
                                    set estado=0 
                                    where id_estudiante = param1 and
                                    id_carrera = param2    and                   
                                    estado = 1";

                string sqlInsert = @"insert into dbo.T_Estudiante_Carrera(id_estudiante, id_carrera)
                                    values(param1, param2)";

                Parametros[] paramUpdate = new Parametros[2];
                paramUpdate[0] = new Parametros(pIdEstudiante, "param1");


                Parametros[] paramInsert = new Parametros[2];
                paramInsert[0] = new Parametros(pIdEstudiante, "param1");

                Modulo.comparaListas(pIdsAP, pIdsBD, sqlUpdate, sqlInsert, paramUpdate, paramInsert, bitacora, null);
            }
            catch (Exception ex)
            {
                throw ex;
            }
        }


        internal List<EsCarrera> listarCarrerasEstudiante(int pidEstudiante)//parametros del grupo
        {
            List<EsCarrera> carreras = new List<EsCarrera>();

            EsCarrera carrera;
            string psp = @"dbo.sp_buscar_carreras_de_un_estudiante";

            Parametros[] parametros = new Parametros[1];
            parametros[0] = new Parametros(pidEstudiante, "idEstudiante");

            try
            {
                SqlDataReader reader = _acceso.execute_SP_Consulta(psp, parametros);

                while (reader.Read())
                {
                    carrera = new EsCarrera();
                    carrera.Id = reader.GetInt32(0) + "";
                    carrera.Codigo = reader.GetValue(1).ToString();
                    carrera.Nombre = reader.GetValue(2).ToString();
                    carreras.Add(carrera);
                }
                reader.Close();

                return carreras;

            }
            catch (Exception ex)
            {
                throw new System.Exception(ex.Message);
            }

        }




        internal List<EsCarrera> listarCarrerasDirectorAcademico(int pidDA)//parametros del grupo
        {
            List<EsCarrera> carreras = new List<EsCarrera>();

            EsCarrera carrera;
            string psp = @"dbo.listar_carreras_director_academico";

            Parametros[] parametros = new Parametros[1];
            parametros[0] = new Parametros(pidDA, "idDA");

            try
            {
                SqlDataReader reader = _acceso.execute_SP_Consulta(psp, parametros);

                while (reader.Read())
                {
                    carrera = new EsCarrera();
                    carrera.Id = reader.GetInt32(0) + "";
                    carrera.Codigo = reader.GetValue(1).ToString();
                    carrera.Nombre = reader.GetValue(2).ToString();
                    carreras.Add(carrera);
                }
                reader.Close();

                return carreras;

            }
            catch (Exception ex)
            {
                throw new System.Exception(ex.Message);
            }

        }


        internal List<EsCarrera> listarCarrerasSinDirectorAcademico()//parametros del grupo
        {
            List<EsCarrera> carreras = new List<EsCarrera>();

            EsCarrera carrera;
            string psp = @"dbo.sp_listar_carreras_sin_director ";

          

            try
            {
                SqlDataReader reader = _acceso.execute_SP_Consulta(psp, null);

                while (reader.Read())
                {
                    carrera = new EsCarrera();
                    carrera.Id = reader.GetInt32(0) + "";
                    carrera.Codigo = reader.GetValue(1).ToString();
                    carrera.Nombre = reader.GetValue(2).ToString();
                    carreras.Add(carrera);
                }
                reader.Close();

                return carreras;

            }
            catch (Exception ex)
            {
                throw new System.Exception(ex.Message);
            }

        }

        /// <summary>
        /// Método de la clase que busca los ids de las carreras de un director.
        /// </summary>
        /// <param name="pIdGrupo">In del grupo, tipo int</param>
        /// <remarks></remarks>
        internal List<Cl_Carrera> buscarIdsCarrerasDeDirector(int pIdDir)
        {
            string psp = @"dbo.sp_listar_carreras_dir";
            Parametros[] parametros = new Parametros[1];
            parametros[0] = new Parametros(pIdDir, "id_director");

            try
            {
                SqlDataReader reader = _acceso.execute_SP_Consulta(psp, parametros);
                List<Cl_Carrera> listaCarreras = new List<Cl_Carrera>();
                while (reader.Read())
                {
                    listaCarreras.Add(new Cl_Carrera(reader.GetString(reader.GetOrdinal("codigo_carrera")), reader.GetString(reader.GetOrdinal("nombre"))));
                }

                reader.Close();
                return listaCarreras;

            }
            catch (Exception ex)
            {
                throw ex;
            }

        }


        /// <summary>
        /// Método de la clase que buscar todas las carreras del sistema.
        /// </summary>
        /// <remarks></remarks>
        public List<EsCarrera> buscarTodasLasCarreras()
        {
            string psp = @"dbo.sp_buscar_todas_las_carreras";
            List<EsCarrera> carreras = new List<EsCarrera>();
 
            try
            {
                SqlDataReader reader = _acceso.execute_SP_Consulta(psp, null);

                while (reader.Read())
                {
                    EsCarrera temp = new EsCarrera(reader.GetInt32(0) + "",
                                                     reader.GetString(1),
                                                    reader.GetString(2));
                    carreras.Add(temp);
                }

                reader.Close();
                return carreras;

            }
            catch (Exception ex)
            {
                throw ex;
            }

        }

        /// <summary>
        /// Método de la clase que buscar todas las carreras del sistema asociadas a un curso.
        /// </summary>
        /// <remarks></remarks>
        public List<EsCarrera> buscarCarrerasAsociadasCurso(int pid)
        {
            string psp = @"dbo.sp_listar_carreras_Curso";
            List<EsCarrera> carreras = new List<EsCarrera>();

            Parametros[] parametros = new Parametros[1];
            parametros[0] = new Parametros(pid, "id_curso");

            try
            {
                SqlDataReader reader = _acceso.execute_SP_Consulta(psp, parametros);

                while (reader.Read())
                {
                    EsCarrera temp = new EsCarrera(reader.GetInt32(0) + "",
                                                    reader.GetString(1),
                                                    reader.GetString(2));
                    carreras.Add(temp);
                }

                reader.Close();
                return carreras;

            }
            catch (Exception ex)
            {
                throw ex;
            }

        }

        /// <summary>
        /// Método de la clase que busca los ids de las carreras de un estudiante.
        /// </summary>
        /// <param name="pIdGrupo">In del grupo, tipo int</param>
        /// <remarks></remarks>
        internal List<int> buscarIdsCarrerasDeCurso(int pid)
        {

            string psp = @"dbo.sp_listar_carreras_Curso";
            Parametros[] parametros = new Parametros[1];
            parametros[0] = new Parametros(pid, "id_curso");

            try
            {
                SqlDataReader reader = (SqlDataReader)_acceso.execute_SP_Consulta(psp, parametros);
                List<int> ids = new List<int>();
                while (reader.Read())
                {
                    ids.Add(reader.GetInt32(0));
                }

                reader.Close();
                return ids;

            }
            catch (Exception ex)
            {
                throw ex;
            }

        }

     
    }
}
